import React, { forwardRef } from 'react';

import { ReactComponent as Check } from '@/assets/images/auth/Check.svg';
import { ReactComponent as Close } from '@/assets/images/profile/CloseSearch.svg';
import { ReactComponent as Search } from '@/assets/images/profile/SearchSmall.svg';
import { ReactComponent as Chevron } from '@/assets/images/shared/icon-chevron.svg';
import { IOption } from '@/shared/interfaces';
import { useMetaTag } from '@/shared/lib/hooks';
import { Modal, Title } from '@/shared/ui';
import cn from 'classnames';
import { useWindowSize } from 'usehooks-ts';

import cs from './SearchInput.module.scss';

export interface SearchInputProps
  extends React.DetailedHTMLProps<React.InputHTMLAttributes<HTMLInputElement>, HTMLInputElement> {
  options: IOption[];
  onSelectClick: (option: any) => void;
  isOpen: boolean;
  activeOption: any;
  isSelect?: boolean;
  isAnotherInput?: boolean;
  isClose?: boolean;
  onClear?: () => void;
  onClose: () => void;
  title: string;
  pagination?: {
    offset: number;
    timeout: boolean;
    callback: () => void;
  } | null;
  text?: string;
}

export const SearchInput = forwardRef<HTMLInputElement, SearchInputProps>(
  (
    {
      options,
      onSelectClick,
      isOpen,
      onClear,
      isAnotherInput,
      activeOption,
      onClose,
      isClose,
      pagination,
      isSelect,
      text,
      id,
      title,
      ...props
    }: SearchInputProps,
    ref,
  ) => {
    const { width } = useWindowSize();
    useMetaTag(isOpen && width < 1024, '#999999');
    const inputRef = React.useRef<HTMLInputElement>(null);
    const observeContainerRef = React.useRef<HTMLDivElement>(null);
    const mobileObserveContainerRef = React.useRef<HTMLDivElement>(null);

    const handleIntersection = (entries: IntersectionObserverEntry[]) => {
      const target = entries[0];
      if (target.isIntersecting && pagination && !pagination.timeout) {
        pagination.callback();
      }
    };

    React.useEffect(() => {
      if (isOpen && pagination) {
        const options = {
          root: width > 1024 ? observeContainerRef.current : null,
          rootMargin: '0px',
          threshold: 1,
        };

        const observer = new IntersectionObserver(handleIntersection, options);

        const lastElement =
          width > 1024
            ? observeContainerRef.current?.lastElementChild
            : mobileObserveContainerRef.current?.lastElementChild;

        if (lastElement) {
          observer.observe(lastElement);
        }

        return () => {
          if (lastElement) {
            observer.unobserve(lastElement);
          }
        };
      }
    }, [isOpen, pagination]);

    return (
      <>
        <label className={cs.label} htmlFor={id} style={{ position: 'relative' }}>
          {isSelect && (
            <span className={cn(cs.chevron, isOpen && width > 1024 && cs.chevron_open)}>
              <Chevron />
            </span>
          )}
          <input className={cn(cs.input, isSelect && cs.select_input)} ref={ref || inputRef} {...props} />
          {isOpen && width > 1024 && (
            <div className={cs.container} ref={observeContainerRef}>
              {options?.map((item) => (
                <div
                  className={cn(cs.option, activeOption?.id === item.value && cs.active_option)}
                  key={item.value}
                  onClick={() => {
                    onSelectClick(item);
                  }}
                >
                  {item.label}
                </div>
              ))}
            </div>
          )}
        </label>
        {width < 1024 && (
          <Modal containerClassName={cs.modal} isMobile isOpen={isOpen} onCloseClick={onClose} zIndex={1500}>
            <Title size="modal-size">{title}</Title>
            <label className={cs.label_container} htmlFor={id} style={{ position: 'relative' }}>
              {!isAnotherInput && <input className={cs.input} {...props} ref={inputRef} />}
              {isAnotherInput && (
                <>
                  <span className={cs.search}>
                    <Search />
                  </span>
                  {isClose && (
                    <span className={cs.close} onClick={onClear}>
                      <Close />
                    </span>
                  )}
                  <input
                    className={cs.another_input}
                    {...props}
                    aria-label="another_input"
                    placeholder=""
                    ref={inputRef}
                  />
                </>
              )}
              <p className={cs.text}>{text}</p>
              <div className={cs.container_mobile} ref={mobileObserveContainerRef}>
                {options?.map((item) => (
                  <div
                    className={cn(cs.option_mobile)}
                    key={item.value}
                    onClick={() => {
                      onSelectClick(item);
                    }}
                  >
                    {item.label}
                    {item.value === activeOption?.id && (
                      <div className={cs.check}>
                        <Check />
                      </div>
                    )}
                  </div>
                ))}
              </div>
            </label>
          </Modal>
        )}
      </>
    );
  },
);
